home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 1 Issue 2 / PDCD-1 - Issue 02.iso / _utilities / utilities / 001 / fue / c / WINDOW < prev    next >
Text File  |  1991-06-08  |  25KB  |  808 lines

  1. /*
  2.  * Window management. Some of the functions are internal, and some are
  3.  * attached to keys that the user actually types.
  4.  */
  5.  
  6. #include        <stdio.h>
  7. #include        "estruct.h"
  8. #include        "etype.h"
  9. #include        "edef.h"
  10. #include        "elang.h"
  11.  
  12. /*
  13.  * Reposition dot in the current window to line "n". If the argument is
  14.  * positive, it is that line. If it is negative it is that line from the
  15.  * bottom. If it is 0 the window is centered (this is what the standard
  16.  * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  17.  */
  18.  
  19. /*{{{  PASCAL NEAR reposition(f, n)*/
  20. PASCAL NEAR reposition(f, n)
  21.     {
  22.     if (f == FALSE)     /* default to 0 to center screen */
  23.         n = 0;
  24.     curwp->w_force = n;
  25.     curwp->w_flag |= WFFORCE;
  26.     return (TRUE);
  27.     }
  28.  
  29. /*}}}*/
  30.  
  31. /*
  32.  * Refresh the screen. With no argument, it just does the refresh. With an
  33.  * argument it recenters "." in the current window. Bound to "C-L".
  34.  */
  35.  
  36. /*{{{  PASCAL NEAR refresh(f, n)*/
  37. PASCAL NEAR refresh(f, n)
  38.     {
  39.     if (f == FALSE)
  40.         sgarbf = TRUE;
  41.     else
  42.         {
  43.         curwp->w_force = 0;             /* Center dot. */
  44.         curwp->w_flag |= WFFORCE;
  45.         }
  46.  
  47.     return (TRUE);
  48.     }
  49. /*}}}*/
  50.  
  51. /*
  52.  * The command make the next window (next => down the screen) the current
  53.  * window. There are no real errors, although the command does nothing if
  54.  * there is only 1 window on the screen. Bound to "C-X C-N".
  55.  *
  56.  * with an argument this command finds the <n>th window from the top
  57.  *
  58.  */
  59. /*{{{  PASCAL NEAR nextwind(f, n)*/
  60. PASCAL NEAR nextwind(f, n)
  61.  
  62. int f, n;       /* default flag and numeric argument */
  63.  
  64. {
  65.         register WINDOW *wp;
  66.         register int nwindows;          /* total number of windows */
  67.  
  68.         if (f) {
  69.  
  70.                 /* first count the # of windows */
  71.                 wp = wheadp;
  72.                 nwindows = 1;
  73.                 while (wp->w_wndp != NULL) {
  74.                         nwindows++;
  75.                         wp = wp->w_wndp;
  76.                 }
  77.  
  78.                 /* if the argument is negative, it is the nth window
  79.                    from the bottom of the screen                        */
  80.                 if (n < 0)
  81.                         n = nwindows + n + 1;
  82.  
  83.                 /* if an argument, give them that window from the top */
  84.                 if (n > 0 && n <= nwindows) {
  85.                         wp = wheadp;
  86.                         while (--n)
  87.                                 wp = wp->w_wndp;
  88.                 } else {
  89.                         mlwrite(TEXT203);
  90. /*                              "Window number out of range" */
  91.                         return(FALSE);
  92.                 }
  93.         } else
  94.                 if ((wp = curwp->w_wndp) == NULL)
  95.                         wp = wheadp;
  96.         curwp = wp;
  97.         curbp = wp->w_bufp;
  98.         upmode();
  99.         return (TRUE);
  100. }
  101. /*}}}*/
  102.  
  103. /*
  104.  * This command makes the previous window (previous => up the screen) the
  105.  * current window. There arn't any errors, although the command does not do a
  106.  * lot if there is 1 window.
  107.  */
  108. /*{{{  PASCAL NEAR prevwind(f, n)*/
  109. PASCAL NEAR prevwind(f, n)
  110. {
  111.         register WINDOW *wp1;
  112.         register WINDOW *wp2;
  113.  
  114.         /* if we have an argument, we mean the nth window from the bottom */
  115.         if (f)
  116.                 return(nextwind(f, -n));
  117.  
  118.         wp1 = wheadp;
  119.         wp2 = curwp;
  120.  
  121.         if (wp1 == wp2)
  122.                 wp2 = NULL;
  123.  
  124.         while (wp1->w_wndp != wp2)
  125.                 wp1 = wp1->w_wndp;
  126.  
  127.         curwp = wp1;
  128.         curbp = wp1->w_bufp;
  129.         upmode();
  130.         return (TRUE);
  131. }
  132. /*}}}*/
  133.  
  134. /*
  135.  * This command moves the current window down by "arg" lines. Recompute the
  136.  * top line in the window. The move up and move down code is almost completely
  137.  * the same; most of the work has to do with reframing the window, and picking
  138.  * a new dot. We share the code by having "move down" just be an interface to
  139.  * "move up". Magic. Bound to "C-X C-N".
  140.  */
  141. /*{{{  PASCAL NEAR mvdnwind(f, n)*/
  142. PASCAL NEAR mvdnwind(f, n)
  143.  
  144. int n;
  145.  
  146. {
  147.         return (mvupwind(f, -n));
  148. }
  149. /*}}}*/
  150.  
  151. /*
  152.  * Move the current window up by "arg" lines. Recompute the new top line of
  153.  * the window. Look to see if "." is still on the screen. If it is, you win.
  154.  * If it isn't, then move "." to center it in the new framing of the window
  155.  * (this command does not really move "."; it moves the frame). Bound to
  156.  * "C-X C-P".
  157.  */
  158. /*{{{  PASCAL NEAR mvupwind(f, n)*/
  159. PASCAL NEAR mvupwind(f, n)
  160.     int n;
  161.  
  162.     {
  163.     register LINE *lp;
  164.     register int i;
  165.  
  166.     lp = curwp->w_linep;
  167.  
  168.     if (n < 0)
  169.         {
  170.         while (n++ && lp!=curbp->b_linep)
  171.             lp = lforw(lp);
  172.         }
  173.     else
  174.         {
  175.         while (n-- && lback(lp)!=curbp->b_linep)
  176.             lp = lback(lp);
  177.         }
  178.  
  179.     curwp->w_linep = lp;
  180.     curwp->w_flag |= WFHARD;            /* Mode line is OK. */
  181.  
  182.     for (i = 0; i < curwp->w_ntrows; ++i)
  183.         {
  184.         if (lp == curwp->w_dotp)
  185.             return (TRUE);
  186.         if (lp == curbp->b_linep)
  187.             break;
  188.         lp = lforw(lp);
  189.         }
  190.  
  191.     lp = curwp->w_linep;
  192.     i  = curwp->w_ntrows/2;
  193.  
  194.     while (i-- && lp != curbp->b_linep)
  195.         lp = lforw(lp);
  196.  
  197.     curwp->w_dotp  = lp;
  198.     curwp->w_doto  = 0;
  199.     return (TRUE);
  200.     }
  201. /*}}}*/
  202.  
  203. /*
  204.  * This command makes the current window the only window on the screen. Bound
  205.  * to "C-X 1". Try to set the framing so that "." does not have to move on the
  206.  * display. Some care has to be taken to keep the values of dot and mark in
  207.  * the buffer structures right if the distruction of a window makes a buffer
  208.  * become undisplayed.
  209.  */
  210.  
  211. /*{{{  PASCAL NEAR onlywind(f, n)*/
  212. PASCAL NEAR onlywind(f, n)
  213. {
  214.         register WINDOW *wp;
  215.         register LINE   *lp;
  216.         register int    i;
  217.         int cmark;              /* current mark */
  218.  
  219.         while (wheadp != curwp) {
  220.                 wp = wheadp;
  221.                 wheadp = wp->w_wndp;
  222.                 if (--wp->w_bufp->b_nwnd == 0) {
  223.                         wp->w_bufp->b_dotp  = wp->w_dotp;
  224.                         wp->w_bufp->b_doto  = wp->w_doto;
  225.                         for (cmark = 0; cmark < NMARKS; cmark++) {
  226.                                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  227.                                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  228.                         }
  229.                         wp->w_bufp->b_fcol  = wp->w_fcol;
  230.                 }
  231.                 free((char *) wp);
  232.         }
  233.         while (curwp->w_wndp != NULL) {
  234.                 wp = curwp->w_wndp;
  235.                 curwp->w_wndp = wp->w_wndp;
  236.                 if (--wp->w_bufp->b_nwnd == 0) {
  237.                         wp->w_bufp->b_dotp  = wp->w_dotp;
  238.                         wp->w_bufp->b_doto  = wp->w_doto;
  239.                         for (cmark = 0; cmark < NMARKS; cmark++) {
  240.                                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  241.                                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  242.                         }
  243.                         wp->w_bufp->b_fcol  = wp->w_fcol;
  244.                 }
  245.                 free((char *) wp);
  246.         }
  247.         lp = curwp->w_linep;
  248.         i  = curwp->w_toprow;
  249.         while (i!=0 && lback(lp)!=curbp->b_linep) {
  250.                 --i;
  251.                 lp = lback(lp);
  252.         }
  253.         curwp->w_toprow = 0;
  254.         curwp->w_ntrows = term.t_nrow-1;
  255.         curwp->w_linep  = lp;
  256.         curwp->w_flag  |= WFMODE|WFHARD;
  257.         return (TRUE);
  258. }
  259. /*}}}*/
  260.  
  261. /*
  262.  * Delete the current window, placing its space in the window above,
  263.  * or, if it is the top window, the window below. Bound to C-X 0.
  264.  */
  265.  
  266. /*{{{  PASCAL NEAR delwind(f,n)*/
  267. PASCAL NEAR delwind(f,n)
  268.  
  269. int f, n;       /* arguments are ignored for this command */
  270.  
  271. {
  272.         register WINDOW *wp;    /* window to recieve deleted space */
  273.         register WINDOW *lwp;   /* ptr window before curwp */
  274.         register int target;    /* target line to search for */
  275.         int cmark;              /* current mark */
  276.  
  277.         /* if there is only one window, don't delete it */
  278.         if (wheadp->w_wndp == NULL) {
  279.                 mlwrite(TEXT204);
  280. /*                      "Can not delete this window" */
  281.                 return(FALSE);
  282.         }
  283.  
  284.         /* find window before curwp in linked list */
  285.         wp = wheadp;
  286.         lwp = NULL;
  287.         while (wp != NULL) {
  288.                 if (wp == curwp)
  289.                         break;
  290.                 lwp = wp;
  291.                 wp = wp->w_wndp;
  292.         }
  293.  
  294.         /* find recieving window and give up our space */
  295.         wp = wheadp;
  296.         if (curwp->w_toprow == 0) {
  297.                 /* find the next window down */
  298.                 target = curwp->w_ntrows + 1;
  299.                 while (wp != NULL) {
  300.                         if (wp->w_toprow == target)
  301.                                 break;
  302.                         wp = wp->w_wndp;
  303.                 }
  304.                 if (wp == NULL)
  305.                         return(FALSE);
  306.                 wp->w_toprow = 0;
  307.                 wp->w_ntrows += target;
  308.         } else {
  309.                 /* find the next window up */
  310.                 target = curwp->w_toprow - 1;
  311.                 while (wp != NULL) {
  312.                         if ((wp->w_toprow + wp->w_ntrows) == target)
  313.                                 break;
  314.                         wp = wp->w_wndp;
  315.                 }
  316.                 if (wp == NULL)
  317.                         return(FALSE);
  318.                 wp->w_ntrows += 1 + curwp->w_ntrows;
  319.         }
  320.  
  321.         /* get rid of the current window */
  322.         if (--curwp->w_bufp->b_nwnd == 0) {
  323.                 curwp->w_bufp->b_dotp  = curwp->w_dotp;
  324.                 curwp->w_bufp->b_doto  = curwp->w_doto;
  325.                 for (cmark = 0; cmark < NMARKS; cmark++) {
  326.                         curwp->w_bufp->b_markp[cmark] = curwp->w_markp[cmark];
  327.                         curwp->w_bufp->b_marko[cmark] = curwp->w_marko[cmark];
  328.                 }
  329.                 curwp->w_bufp->b_fcol  = curwp->w_fcol;
  330.         }
  331.         if (lwp == NULL)
  332.                 wheadp = curwp->w_wndp;
  333.         else
  334.                 lwp->w_wndp = curwp->w_wndp;
  335.         free((char *)curwp);
  336.         curwp = wp;
  337.         wp->w_flag |= WFHARD;
  338.         curbp = wp->w_bufp;
  339.         upmode();
  340.         return(TRUE);
  341. }
  342. /*}}}*/
  343.  
  344. /*
  345.  
  346. Split the current window.  A window smaller than 3 lines cannot be
  347. split.  (Two line windows can be split when mode lines are disabled) An
  348. argument of 1 forces the cursor into the upper window, an argument of
  349. two forces the cursor to the lower window.  The only other error that
  350. is possible is a "malloc" failure allocating the structure for the new
  351. window.  Bound to "C-X 2". 
  352.  
  353. */
  354.  
  355. /*{{{  PASCAL NEAR splitwind(f, n)*/
  356. PASCAL NEAR splitwind(f, n)
  357.  
  358. int f, n;       /* default flag and numeric argument */
  359.  
  360. {
  361.         register WINDOW *wp;
  362.         register LINE   *lp;
  363.         register int    ntru;
  364.         register int    ntrl;
  365.         register int    ntrd;
  366.         register WINDOW *wp1;
  367.         register WINDOW *wp2;
  368.         int cmark;              /* current mark */
  369.  
  370.         /* make sure we have enough space */
  371.         if (curwp->w_ntrows < (modeflag ? 3 : 2)) {
  372.                 mlwrite(TEXT205, curwp->w_ntrows);
  373. /*                      "Cannot split a %d line window" */
  374.                 return (FALSE);
  375.         }
  376.         if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  377.                 mlwrite(TEXT99);
  378. /*                      "[OUT OF MEMORY]" */
  379.                 return (FALSE);
  380.         }
  381.         ++curbp->b_nwnd;                        /* Displayed twice.     */
  382.         wp->w_bufp  = curbp;
  383.         wp->w_dotp  = curwp->w_dotp;
  384.         wp->w_doto  = curwp->w_doto;
  385.         for (cmark = 0; cmark < NMARKS; cmark++) {
  386.                 wp->w_markp[cmark] = curwp->w_markp[cmark];
  387.                 wp->w_marko[cmark] = curwp->w_marko[cmark];
  388.         }
  389.         wp->w_fcol  = curwp->w_fcol;
  390.         wp->w_flag  = 0;
  391.         wp->w_force = 0;
  392. #if     COLOR
  393.         /* set the colors of the new window */
  394.         wp->w_fcolor = gfcolor;
  395.         wp->w_bcolor = gbcolor;
  396. #endif
  397.         ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  398.         ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  399.         lp = curwp->w_linep;
  400.         ntrd = 0;
  401.         while (lp != curwp->w_dotp) {
  402.                 ++ntrd;
  403.                 lp = lforw(lp);
  404.         }
  405.         lp = curwp->w_linep;
  406.         if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  407.                 /* Old is upper window. */
  408.                 if (ntrd == ntru)               /* Hit mode line.       */
  409.                         lp = lforw(lp);
  410.                 curwp->w_ntrows = ntru;
  411.                 wp->w_wndp = curwp->w_wndp;
  412.                 curwp->w_wndp = wp;
  413.                 wp->w_toprow = curwp->w_toprow+ntru+1;
  414.                 wp->w_ntrows = ntrl;
  415.         } else {                                /* Old is lower window  */
  416.                 wp1 = NULL;
  417.                 wp2 = wheadp;
  418.                 while (wp2 != curwp) {
  419.                         wp1 = wp2;
  420.                         wp2 = wp2->w_wndp;
  421.                 }
  422.                 if (wp1 == NULL)
  423.                         wheadp = wp;
  424.                 else
  425.                         wp1->w_wndp = wp;
  426.                 wp->w_wndp   = curwp;
  427.                 wp->w_toprow = curwp->w_toprow;
  428.                 wp->w_ntrows = ntru;
  429.                 ++ntru;                         /* Mode line.           */
  430.                 curwp->w_toprow += ntru;
  431.                 curwp->w_ntrows  = ntrl;
  432.                 while (ntru--)
  433.                         lp = lforw(lp);
  434.         }
  435.         curwp->w_linep = lp;                    /* Adjust the top lines */
  436.         wp->w_linep = lp;                       /* if necessary.        */
  437.         curwp->w_flag |= WFMODE|WFHARD;
  438.         wp->w_flag |= WFMODE|WFHARD;
  439.         return (TRUE);
  440. }
  441. /*}}}*/
  442.  
  443. /*
  444.  * Enlarge the current window. Find the window that loses space. Make sure it
  445.  * is big enough. If so, hack the window descriptions, and ask redisplay to do
  446.  * all the hard work. You don't just set "force reframe" because dot would
  447.  * move. Bound to "C-X Z".
  448.  */
  449.  
  450. /*{{{  PASCAL NEAR enlargewind(f, n)*/
  451. PASCAL NEAR enlargewind(f, n)
  452. {
  453.         register WINDOW *adjwp;
  454.         register LINE   *lp;
  455.         register int    i;
  456.  
  457.         if (n < 0)
  458.                 return (shrinkwind(f, -n));
  459.         if (wheadp->w_wndp == NULL) {
  460.                 mlwrite(TEXT206);
  461. /*                      "Only one window" */
  462.                 return (FALSE);
  463.         }
  464.         if ((adjwp=curwp->w_wndp) == NULL) {
  465.                 adjwp = wheadp;
  466.                 while (adjwp->w_wndp != curwp)
  467.                         adjwp = adjwp->w_wndp;
  468.         }
  469.         if ((adjwp->w_ntrows + (modeflag ? 0 : 1)) <= n) {
  470.                 mlwrite(TEXT207);
  471. /*                      "Impossible change" */
  472.                 return (FALSE);
  473.         }
  474.         if (curwp->w_wndp == adjwp) {           /* Shrink below.        */
  475.                 lp = adjwp->w_linep;
  476.                 for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  477.                         lp = lforw(lp);
  478.                 adjwp->w_linep  = lp;
  479.                 adjwp->w_toprow += n;
  480.         } else {                                /* Shrink above.        */
  481.                 lp = curwp->w_linep;
  482.                 for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  483.                         lp = lback(lp);
  484.                 curwp->w_linep  = lp;
  485.                 curwp->w_toprow -= n;
  486.         }
  487.         curwp->w_ntrows += n;
  488.         adjwp->w_ntrows -= n;
  489.         curwp->w_flag |= WFMODE|WFHARD;
  490.         adjwp->w_flag |= WFMODE|WFHARD;
  491.         return (TRUE);
  492. }
  493. /*}}}*/
  494.  
  495. /*
  496.  * Shrink the current window. Find the window that gains space. Hack at the
  497.  * window descriptions. Ask the redisplay to do all the hard work. Bound to
  498.  * "C-X C-Z".
  499.  */
  500.  
  501. /*{{{  PASCAL NEAR shrinkwind(f, n)*/
  502. PASCAL NEAR shrinkwind(f, n)
  503. {
  504.         register WINDOW *adjwp;
  505.         register LINE   *lp;
  506.         register int    i;
  507.  
  508.         if (n < 0)
  509.                 return (enlargewind(f, -n));
  510.         if (wheadp->w_wndp == NULL) {
  511.                 mlwrite(TEXT206);
  512. /*                      "Only one window" */
  513.                 return (FALSE);
  514.         }
  515.         if ((adjwp=curwp->w_wndp) == NULL) {
  516.                 adjwp = wheadp;
  517.                 while (adjwp->w_wndp != curwp)
  518.                         adjwp = adjwp->w_wndp;
  519.         }
  520.         if ((curwp->w_ntrows + (modeflag ? 0 : 1)) <= n) {
  521.                 mlwrite(TEXT207);
  522. /*                      "Impossible change" */
  523.                 return (FALSE);
  524.         }
  525.         if (curwp->w_wndp == adjwp) {           /* Grow below.          */
  526.                 lp = adjwp->w_linep;
  527.                 for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  528.                         lp = lback(lp);
  529.                 adjwp->w_linep  = lp;
  530.                 adjwp->w_toprow -= n;
  531.         } else {                                /* Grow above.          */
  532.                 lp = curwp->w_linep;
  533.                 for (i=0; i<n && lp!=curbp->b_linep; ++i)
  534.                         lp = lforw(lp);
  535.                 curwp->w_linep  = lp;
  536.                 curwp->w_toprow += n;
  537.         }
  538.         curwp->w_ntrows -= n;
  539.         adjwp->w_ntrows += n;
  540.         curwp->w_flag |= WFMODE|WFHARD;
  541.         adjwp->w_flag |= WFMODE|WFHARD;
  542.         return (TRUE);
  543. }
  544. /*}}}*/
  545.  
  546. /*      Resize the current window to the requested size */
  547.  
  548. /*{{{  PASCAL NEAR resize(f, n)*/
  549. PASCAL NEAR resize(f, n)
  550.  
  551. int f, n;       /* default flag and numeric argument */
  552.  
  553. {
  554.         int clines;     /* current # of lines in window */
  555.         
  556.         /* must have a non-default argument, else ignore call */
  557.         if (f == FALSE)
  558.                 return(TRUE);
  559.  
  560.         /* find out what to do */
  561.         clines = curwp->w_ntrows;
  562.  
  563.         /* already the right size? */
  564.         if (clines == n)
  565.                 return(TRUE);
  566.  
  567.         return(enlargewind(TRUE, n - clines));
  568. }
  569. /*}}}*/
  570.  
  571. /*
  572.  * Pick a window for a pop-up. Split the screen if there is only one window.
  573.  * Pick the uppermost window that isn't the current window. An LRU algorithm
  574.  * might be better. Return a pointer, or NULL on error.
  575.  */
  576.  
  577. /*{{{  WINDOW *PASCAL NEAR wpopup()*/
  578. WINDOW *PASCAL NEAR wpopup()
  579.  
  580. {
  581.         register WINDOW *wp;
  582.  
  583.         if (wheadp->w_wndp == NULL              /* Only 1 window        */
  584.         && splitwind(FALSE, 0) == FALSE)        /* and it won't split   */
  585.                 return (NULL);
  586.         wp = wheadp;                            /* Find window to use   */
  587.         while (wp!=NULL && wp==curwp)
  588.                 wp = wp->w_wndp;
  589.         return (wp);
  590. }
  591. /*}}}*/
  592.  
  593. /* scroll the next window up (back) a page */
  594.  
  595. /*{{{  PASCAL NEAR nextup(f, n) */
  596. PASCAL NEAR nextup(f, n) 
  597.  
  598. {
  599.         nextwind(FALSE, 1);
  600.         backpage(f, n);
  601.         prevwind(FALSE, 1);
  602. }
  603. /*}}}*/
  604.  
  605. /* scroll the next window down (forward) a page */
  606.  
  607. /*{{{  PASCAL NEAR nextdown(f, n)*/
  608. PASCAL NEAR nextdown(f, n)
  609.  
  610. {
  611.         nextwind(FALSE, 1);
  612.         forwpage(f, n);
  613.         prevwind(FALSE, 1);
  614. }
  615. /*}}}*/
  616.  
  617. /* save ptr to current window */
  618.  
  619. /*{{{  PASCAL NEAR savewnd(f, n)*/
  620. PASCAL NEAR savewnd(f, n)
  621.  
  622. {
  623.         swindow = curwp;
  624.         return(TRUE);
  625. }
  626. /*}}}*/
  627.  
  628. /* restore the saved screen */
  629.  
  630. /*{{{  PASCAL NEAR restwnd(f, n)*/
  631. PASCAL NEAR restwnd(f, n)
  632.  
  633. {
  634.         register WINDOW *wp;
  635.  
  636.         /* find the window */
  637.         wp = wheadp;
  638.         while (wp != NULL) {
  639.                 if (wp == swindow) {
  640.                         curwp = wp;
  641.                         curbp = wp->w_bufp;
  642.                         upmode();
  643.                         return (TRUE);
  644.                 }
  645.                 wp = wp->w_wndp;
  646.         }
  647.  
  648.         mlwrite(TEXT208);
  649. /*              "[No such window exists]" */
  650.         return(FALSE);
  651. }
  652. /*}}}*/
  653.  
  654. /* resize the screen, re-writing the screen */
  655.  
  656. /*{{{  PASCAL NEAR newsize(f, n)*/
  657. PASCAL NEAR newsize(f, n)
  658.  
  659. int f;  /* default flag */
  660. int n;  /* numeric argument */
  661.  
  662. {
  663.         WINDOW *wp;     /* current window being examined */
  664.         WINDOW *nextwp; /* next window to scan */
  665.         WINDOW *lastwp; /* last window scanned */
  666.         int lastline;   /* screen line of last line of current window */
  667.         int cmark;              /* current mark */
  668.  
  669.         /* if the command defaults, assume the largest */
  670.         if (f == FALSE)
  671.                 n = term.t_mrow + 1;
  672.  
  673.         /* make sure it's in range */
  674.         if (n < 3 || n > term.t_mrow + 1) {
  675.                 mlwrite(TEXT209);
  676. /*                      "%%Screen size out of range" */
  677.                 return(FALSE);
  678.         }
  679.  
  680.         if (term.t_nrow == n - 1)
  681.                 return(TRUE);
  682.         else if (term.t_nrow < n - 1) {
  683.  
  684.                 /* go to the last window */
  685.                 wp = wheadp;
  686.                 while (wp->w_wndp != NULL)
  687.                         wp = wp->w_wndp;
  688.  
  689.                 /* and enlarge it as needed */
  690.                 wp->w_ntrows = n - wp->w_toprow - 2;
  691.                 wp->w_flag |= WFHARD|WFMODE;
  692.  
  693.         } else {
  694.  
  695.                 /* rebuild the window structure */
  696.                 nextwp = wheadp;
  697.                 wp = NULL;
  698.                 lastwp = NULL;
  699.                 while (nextwp != NULL) {
  700.                         wp = nextwp;
  701.                         nextwp = wp->w_wndp;
  702.         
  703.                         /* get rid of it if it is too low */
  704.                         if (wp->w_toprow > n - 2) {
  705.  
  706.                                 /* save the point/mark if needed */
  707.                                 if (--wp->w_bufp->b_nwnd == 0) {
  708.                                         wp->w_bufp->b_dotp = wp->w_dotp;
  709.                                         wp->w_bufp->b_doto = wp->w_doto;
  710.                                         for (cmark = 0; cmark < NMARKS; cmark++) {
  711.                                                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  712.                                                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  713.                                         }
  714.                                         wp->w_bufp->b_fcol = wp->w_fcol;
  715.                                 }
  716.         
  717.                                 /* update curwp and lastwp if needed */
  718.                                 if (wp == curwp)
  719.                                         curwp = wheadp;
  720.                                         curbp = curwp->w_bufp;
  721.                                 if (lastwp != NULL)
  722.                                         lastwp->w_wndp = NULL;
  723.  
  724.                                 /* free the structure */
  725.                                 free((char *)wp);
  726.                                 wp = NULL;
  727.  
  728.                         } else {
  729.                                 /* need to change this window size? */
  730.                                 lastline = wp->w_toprow + wp->w_ntrows - 1;
  731.                                 if (lastline >= n - 2) {
  732.                                         wp->w_ntrows = n - wp->w_toprow - 2;
  733.                                         wp->w_flag |= WFHARD|WFMODE;
  734.                                 }
  735.                         }
  736.         
  737.                         lastwp = wp;
  738.                 }
  739.         }
  740.  
  741.         /* screen is garbage */
  742.         term.t_nrow = n - 1;
  743.         sgarbf = TRUE;
  744.         return(TRUE);
  745. }
  746. /*}}}*/
  747.  
  748. /* resize the screen, re-writing the screen */
  749.  
  750. /*{{{  PASCAL NEAR newwidth(f, n)*/
  751. PASCAL NEAR newwidth(f, n)
  752.  
  753. int f;  /* default flag */
  754. int n;  /* numeric argument */
  755.  
  756. {
  757.         register WINDOW *wp;
  758.  
  759.         /* if the command defaults, assume the largest */
  760.         if (f == FALSE)
  761.                 n = term.t_mcol;
  762.  
  763.         /* make sure it's in range */
  764.         if (n < 10 || n > term.t_mcol) {
  765.                 mlwrite(TEXT210);
  766. /*                      "%%Screen width out of range" */
  767.                 return(FALSE);
  768.         }
  769.  
  770.         /* otherwise, just re-width it (no big deal) */
  771.         term.t_ncol = n;
  772.         term.t_margin = n / 10;
  773.         term.t_scrsiz = n - (term.t_margin * 2);
  774.  
  775.         /* florce all windows to redraw */
  776.         wp = wheadp;
  777.         while (wp) {
  778.                 wp->w_flag |= WFHARD | WFMOVE | WFMODE;
  779.                 wp = wp->w_wndp;
  780.         }
  781.         sgarbf = TRUE;
  782.  
  783.         return(TRUE);
  784. }
  785. /*}}}*/
  786.  
  787. /* get screen offset of current line in current window */
  788.  
  789. /*{{{  int PASCAL NEAR getwpos()*/
  790. int PASCAL NEAR getwpos()
  791.  
  792. {
  793.         register int sline;     /* screen line from top of window */
  794.         register LINE *lp;      /* scannile line pointer */
  795.  
  796.         /* search down the line we want */
  797.         lp = curwp->w_linep;
  798.         sline = 1;
  799.         while (lp != curwp->w_dotp) {
  800.                 ++sline;
  801.                 lp = lforw(lp);
  802.         }
  803.  
  804.         /* and return the value */
  805.         return(sline);
  806. }
  807. /*}}}*/
  808.